#pragma once

#include <qlib/all.h>
#include "../layout/layout.hpp"
#include "../render/components.hpp"

#include "./components.hpp"

namespace qbe::select {

enum struct SelectBoxDirect : uint8_t {
  None = 0,
  Left = 1,
  Right = 2,
};

enum struct DrawBoxDirect : uint8_t {
  None = 0,
  Left = 1,
  Right = 2,
};

struct Rect {
  double x, y, width, height;
};

struct HoverModel {
  bool run{false};      // 预选
  entt::entity entity;  // 预选对象
};

using SelectPartType = qlib::GeoPartType;

struct SelectPartData {
  qlib::Vec2dArray points;
  std::map<uint32_t, bool> point_id_map;
  std::map<uint32_t, bool> edge_id_map;

  qlib::Vec2dArray get_edge(uint32_t id) { return qlib::Vec2dArray{points[id], points[(id + 1) % points.size()]}; };
  qlib::Vec2d get_point(uint32_t id) { return points[id % points.size()]; };

  bool operator!=(SelectPartData& data) const {
    return points != data.points || point_id_map != data.point_id_map || edge_id_map != data.edge_id_map;
  }
};

enum struct PartType {
  None = 0,
  Point,        // 顶点
  Center,       // 中心点
  Edge,         // 边
  EdgeMid,      // 边中点
  BoxPoint,     // box顶点
  BoxEdge,      // box边
  BoxEdgeMid,   // box边中点
  ArcStart,     // 圆弧起点
  ArcEnd,       // 圆弧终点
  ArcCenter,    // 圆弧中点
  Arc,          // 扇形圆弧
  RadiusStart,  // 扇形起始半径
  RadiusEnd,    // 扇形终止圆弧
};

struct PartData {
  qlib::Vec2dArray points;
  std::map<uint32_t, PartType> point_id_map;
  std::map<uint32_t, PartType> edge_id_map;
  qlib::Vec2dArray get_edge(uint32_t id) { return qlib::Vec2dArray{points[id], points[(id + 1) % points.size()]}; };
  qlib::Vec2d get_point(uint32_t id) { return points[id % points.size()]; };
};

// 弃用
struct SelectPartModel {
  struct Part {
    qlib::Vec2dArray points;
    std::map<uint32_t, bool> point_id_map;
    std::map<uint32_t, bool> edge_id_map;
  };

  struct Data {
    entt::entity entity;     // 几何实体
    uint32_t id;             // 几何部分索引, 配合下面的type使用
    SelectPartType type;     // 几何部分类型
    qlib::GeoType geo_type;  // 几何对象类型

    bool is_render{true};  // 是否渲染

    qlib::Vec2dArray points;  // 已弃用，部分选择的获取原始点, 根据id和type可以从这里获取相应的对象

    render::PointMesh point_mesh;  // 渲染点
    render::LineMesh edge_mesh;    // 渲染边

    qlib::Vec2d point;      // 提取的点对象
    qlib::Vec2dArray edge;  // 提取的边对象

    struct Hash {
      std::size_t operator()(const Data& it) const {
        return std::hash<uint32_t>()(static_cast<uint64_t>(it.entity) ^ (static_cast<uint8_t>(it.type) << 8) ^ (static_cast<uint16_t>(it.id) << 16));
      }
    };

    bool operator==(const Data& rh) const { return entity == rh.entity && type == rh.type && id == rh.id; }
    bool operator!=(const Data& rh) const { return !(*this == rh); }
    // 定义严格弱序比较（按 x→y→z 的优先级）
    bool operator<(const Data& b) { return entity < b.entity; }

    void clear() {
      entity = entt::null;
      id = 0;
      type = SelectPartType::None;
      point = {};
      edge.clear();
    }
  };

  void add_select(const Data& d) { selects.push_back(d); }
  void add_hover(const Data& d) { hovers.push_back(d); }
  void clear_selected_points(bool& changed) {
    //清除点，只保留边的选择
    int size_before = selects.size();
    std::vector<Data> filter_res;
    for (auto item : selects) {
      if (item.type == select::SelectPartType::Edge || item.type == select::SelectPartType::BoxEdge || item.type == select::SelectPartType::Arc ||
          item.type == select::SelectPartType::RadiusStart || item.type == select::SelectPartType::RadiusEnd)
        filter_res.push_back(item);
    }
    selects = filter_res;
    changed = filter_res.size() != size_before;
  }

  void disable() {
    enable_multi = false;
    enable_box = false;
    enable_hover = false;
    enable_one = false;
  }

  void enable() {
    enable_multi = true;
    enable_box = true;
    enable_hover = true;
    enable_one = true;
  }

  //
  bool run;  // 功能运行

  //
  bool mode_change{false};  // 模式切换

  // 功能控制标志
  bool enable_multi{true};   // 多选 shift + mouse
  bool enable_box{true};     // 框选
  bool enable_hover{true};   // 预选
  bool enable_one{true};     // 单选
  bool enable_render{true};  // 渲染

  bool enable_op_point{true};   // 控制-选择点
  bool enable_op_edge{true};    // 控制-选择边
  bool enable_op_ref{false};    // 控制-选择引用
  bool quick_align_run{false};  // 快速对其功能是否开启

  std::vector<Data> hovers;   // 弃用
  std::vector<Data> selects;  // 弃用

  std::unordered_map<entt::entity, Part> select_parts;  // 选择对象
  std::unordered_map<entt::entity, Part> hover_parts;   // 预选对象

  Data hover;   // 弃用, 预选对象
  Data select;  // 弃用, 选择对象

  // // 绘制矩形框
  // bool box_exist;
  // qlib::Rectangle::s_ptr box_rect;
  // DrawBoxDirect box_direct;  // 框选方向：1: 左，2: 右
  // bool box_render{false};    // box渲染
  // render::BoxMesh box_mesh;

  // // 鼠标事件
  // bool mouse_move{false};
  // bool mouse_press{false};
  // double mouse_press_x, mouse_press_y;
  // bool mouse_release{false};
  // // 键盘事件
  // bool key_shift_press{false};  // shift按键, 多选按键
  // bool key_ctrl_press{false};   // 多选取消
};

enum struct OverallOperatorType {
  None = 0,
  One,    // 单选
  Multi,  // 多选
  Box,    // 框选
  All,    // 全选
};

class OverallModel {
 public:
  ~OverallModel(){};
  OverallModel(){};

  void remove(const qlib::Tag& tag){};
  void clear_hover(){};
  void clear_select(){};
  void clear_parts(){};
  void clear_all(){};

  bool is_move() { return is_move_flag; }

  void render(){};
  void disable(){};
  void enable(){};

  qlib::Cell::s_ptr cell;

  std::unordered_map<entt::entity, SelectPartData> select_parts;  // 部分-选择对象
  std::unordered_map<entt::entity, SelectPartData> hover_parts;   // 部分-预选对象

  // 部分选择对象- 点对齐，线对齐
  std::unordered_map<entt::entity, SelectPartData> algin_select_parts;        // 部分-选择对象
  std::unordered_map<entt::entity, SelectPartData> center_line_select_parts;  // 中心线-选择对象

  // 模式切换
  int mode{0};  //0: None 1: 部分选择， 2： 选择
  state::EditingModeType edit_mode;
  state::EditingChildMode edit_child_mode;

  bool is_move_flag{false};

  // 刷新
  bool select_render{false};
  bool hover_render{false};
  bool select_part_render{false};
  bool hover_part_render{false};

  // 模式切换
  bool mode_change{false};
  // 操作类型
  OverallOperatorType op_type;
  // 功能控制标志
  bool enable_multi{true};   // 多选 shift + mouse
  bool enable_box{true};     // 框选
  bool enable_hover{true};   // 预选
  bool enable_one{true};     // 单选
  bool enable_all{true};     // 全选
  bool enable_render{true};  // 渲染
  // 部分选择控制标志
  bool enable_op_point{true};   // 控制-选择点
  bool enable_op_edge{true};    // 控制-选择边
  bool enable_op_ref{false};    // 控制-选择引用
  bool quick_align_run{false};  // 快速对其功能是否开启
  // 鼠标事件
  bool mouse_move{false};
  bool mouse_press{false};
  double mouse_press_x, mouse_press_y;
  bool mouse_release{false};
  bool key_shift_press{false};  // shift按键, 多选按键
  bool key_ctrl_press{false};   // 多选取消
  // 预选对象
  entt::entity hover_entity{entt::null};
  // 绘制矩形框
  bool box_exist{false};
  qlib::Rectangle::s_ptr box_rect;
  DrawBoxDirect box_direct{DrawBoxDirect::None};  // 框选方向：1: 左，2: 右
  render::BoxMesh box_mesh;
  // 选择切换及优先级
  bool order{false};
  bool order_exist{false};
  uint32_t order_cnt{0};
  std::multimap<double, entt::entity> order_borders;  // 边框
  std::multimap<double, entt::entity> order_areas;    // 区域
  void order_reset() {
    order = false;
    order_exist = false;
    order_cnt = 0;
    order_borders.clear();
    order_areas.clear();
  }
};

struct SelectModel {

  qlib::CellQuad::NodeArray mouse_surround_nodes;

  std::vector<entt::entity> getSelectObj() {
    std::vector<entt::entity> res;
    res.reserve((entity_one == entt::null ? 0 : 1) + entity_arr.size());
    if (entity_one != entt::null) {
      res.push_back(entity_one);
    }
    res.insert(res.end(), entity_arr.begin(), entity_arr.end());
    return res;
  }

  bool run{true};

  bool is_hover{false};       // 预选
  bool has_hover{false};      // 存在预选
  entt::entity entity_hover;  // 预选对象

  bool is_one{false};                    // 单选
  entt::entity entity_one = entt::null;  // 选中对象

  bool is_box{false};                    // 框选标记
  bool is_exist_box{false};              // 框选框是否存在
  entt::entity entity_box;               // 框选对象
  std::vector<entt::entity> entity_arr;  // 选中对象
  SelectBoxDirect direct;                // 框选方向

  bool is_move{false};  // 移动

  // 鼠标按下位置
  double press_x, press_y;

  // 鼠标控制逻辑
  bool press{false};
  bool release{false};
  bool move{false};

  //0表示不过滤，所有对象都能选择
  //1表示只能选择独立的折线(即：没有拐点,只有一段)(圆角工具),
  //2表示只能选择大于两段线(圆角工具)
  //3表示部分选择只能选择线的线段和点(自动布线拉伸)
  //4表示部分选择下选择线、矩形、多边形的边(中心线功能)
  //5表示部分选择下选择线的线段，不能选择点(自动布线推挤)
  //6表示只能选择骨架线(线添加折角)
  int select_ele_ctrl = 0;
  //是否连续选择多个
  bool is_continuous_select = false;

  void reset() {
    is_move = false;
    entity_one = entt::null;
    entity_arr.clear();
  }
};

}  // namespace qbe::select
